#include "MyStream.h"
//---------------------------------------------------------------------------
#ifdef MY_BORLAND
#include <vcl.h>
#pragma hdrstop
#pragma package(smart_init)
//---------------------------------------------------------------------------
static inline void ValidCtrCheck(MyStream *)
{
	new MyStream(NULL);
}
#endif

MyStream::MyStream()
{
    FSize = 0;   
    FData = NULL; 
#ifdef MY_BORLAND    
    OnLoadData = DummyLoadData;
    OnSaveData = DummySaveData;    
#endif
}
//---------------------------------------------------------------------------
MyStream::~MyStream()
{
    
}
//---------------------------------------------------------------------------
DWORD MyStream::Clear(void)
{
    FSize = 0;
    if(FData != NULL)
        free(FData);
    FData = NULL;
    return STREAM_CORRECT;
}
//---------------------------------------------------------------------------
DWORD MyStream::LoadFromBuffer(void *Buffer, int BufferSize)
{
    DWORD Res = Clear();
    StreamLoadInfo *Info = (StreamLoadInfo*)malloc(sizeof(StreamLoadInfo));
    Info->Source = BUFFER_LOAD_SOURCE;
    Info->LoadSize = BufferSize;
    Info->SourceData = Buffer;
    Info->AddInfo = 0;
    if(Res == STREAM_CORRECT)
    {
        if(BufferSize && Buffer != NULL)
        {
            FData = (unsigned char*)malloc(BufferSize);
            if(FData == NULL)
            {
                Info->Result = STREAM_INVALID_ALLOCATE;
                OnLoadData((DWORD)Info);
                return STREAM_INVALID_ALLOCATE;
            }
            memcpy(FData,Buffer, BufferSize);    
            FSize = BufferSize;
            Info->Result = STREAM_CORRECT;
            OnLoadData((DWORD)Info);            
        }
    }
    else
    {
        Info->Result = Res;
        OnLoadData((DWORD)Info);             
    }
    return Res;    
}
//---------------------------------------------------------------------------
void *MyStream::GetData()
{
    unsigned char *Out = NULL;
    if(FSize != 0)
    {
        Out = (unsigned char*)malloc(FSize);
        memcpy(Out,FData,FSize);    
    }
    return Out;
}
//---------------------------------------------------------------------------
int MyStream::GetSize()
{
    return FSize;
}
//---------------------------------------------------------------------------
void MyStream::SetSize(int NewSize)
{
    if(FSize == 0)
    {
        FSize = NewSize;
        FData = (unsigned char*)malloc(FSize);
        memset(FData,0,FSize);   
    }
    else
    {
        if(FSize<NewSize)
        {
            FData = (unsigned char*)realloc(FData,NewSize);
            memset(FData+FSize,0,NewSize-FSize);
            FSize = NewSize;        
        }    
    }
}
//---------------------------------------------------------------------------
DWORD MyStream::SaveToBuffer(void *Buffer)
{
    StreamLoadInfo *Info = (StreamLoadInfo*)malloc(sizeof(StreamLoadInfo));
    Info->Source = BUFFER_LOAD_SOURCE;
    Info->LoadSize = BufferSize;
    Info->SourceData = Buffer;
    Info->AddInfo = 0;    
    if(FSize)
        memcpy(Buffer,FData,FSize);   
    Info->Result = STREAM_CORRECT;
    OnSaveData((DWORD)Info);        
    return STREAM_CORRECT;
}
//---------------------------------------------------------------------------
DWORD MyStream::LoadFromFile(char *FileName)
{
    DWORD Res = Clear();
    StreamLoadInfo *Info = (StreamLoadInfo*)malloc(sizeof(StreamLoadInfo));
    Info->Source = FILE_LOAD_SOURCE;
    Info->LoadSize = 0;
    Info->SourceData = FileName;
    Info->AddInfo = 0;    
    if(Res == STREAM_CORRECT)
    {
    	FILE  *in;
    	in = fopen(FileName,"rb");   
        if(in == NULL)
        {
            Info->Result = STREAM_INVALID_FILE;
            OnLoadData((DWORD)Info);              
            return STREAM_INVALID_FILE;
        }
        else
        {
            int FS;
            FS = fseek(in,0,SEEK_END);
            if(FS)
            {
                Info->Result = STREAM_ERR_SEEK_FILE;
                OnLoadData((DWORD)Info);                
                return STREAM_ERR_SEEK_FILE;
            }
            FS = ftell(in);
            if(FS == -1L)
            {
                Info->Result = STREAM_ERR_SEEK_FILE;
                OnLoadData((DWORD)Info);                 
                return STREAM_ERR_FTELL_FILE;
            }
            FData = (unsigned char*)malloc(FS);
            if(FData == NULL)
            {
                Info->Result = STREAM_INVALID_ALLOCATE;
                OnLoadData((DWORD)Info);                 
               return STREAM_INVALID_ALLOCATE; 
            }
            FSize =FS;
            FS = fseek(in,0,SEEK_SET);
            if(FS)
            {
                Info->Result = STREAM_ERR_SEEK_FILE;
                OnLoadData((DWORD)Info);                 
                return STREAM_ERR_SEEK_FILE;
            }
            FS = fread(FData,1,FSize,in);
            if(FS != FSize)
            {
                Info->Result = STREAM_WRONG_BYTES_READ;
                OnLoadData((DWORD)Info);     
                return STREAM_WRONG_BYTES_READ;
            }
            FS = fclose(in);
            if(FS)
            {
                Info->Result = STREAM_WRONG_CLOSE;
                OnLoadData((DWORD)Info);     
                return STREAM_WRONG_CLOSE;
            }
            else
            {
                Info->Result = STREAM_CORRECT;
                OnLoadData((DWORD)Info);                     
                return STREAM_CORRECT;
            }
        }     
    } 
    else
    {
        Info->Result = Res;
        OnLoadData((DWORD)Info);             
    }       
    return Res;
}
//---------------------------------------------------------------------------
void MyStream::DummyLoadData(DWORD InfoSource)
{
    
}
//---------------------------------------------------------------------------
void MyStream::DummySaveData(DWORD InfoSource)
{
    
}
//---------------------------------------------------------------------------
#ifndef MY_BORLAND
void MyStream::OnLoadData(DWORD InfoSource)
{
    DummyLoadData(InfoSource);    
}
void MyStream::OnSaveData(DWORD InfoSource)
{
    DummySaveData(InfoSource);    
}
#endif
//---------------------------------------------------------------------------
DWORD MyStream::SaveToFile(char *FileName)
{
    StreamLoadInfo *Info = (StreamLoadInfo*)malloc(sizeof(StreamLoadInfo));
    Info->Source = FILE_LOAD_SOURCE;
    Info->LoadSize = 0;
    Info->SourceData = FileName;
    Info->AddInfo = 0;    
    FILE  *Out;
    Out = fopen(FileName,"wb");
    if(Out != NULL)
    {
        DWORD Res;
        Res = fwrite(FData,1,FSize,Out);
        if(Res != FSize)
        {
            Info->Result = STREAM_WRONG_BYTES_WRT;
            Info->AddInfo = Res;
            OnSaveData((DWORD)Info);
            return STREAM_WRONG_BYTES_WRT;        
        }
        Res = fclose(Out);
        if(Res)
        {
            Info->Result = STREAM_WRONG_CLOSE;
            OnSaveData((DWORD)Info);            
            return STREAM_WRONG_CLOSE;
        }        
    }
    Info->Result = STREAM_CORRECT;
    OnSaveData((DWORD)Info);       
    return STREAM_CORRECT;    
}
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------

//---------------------------------------------------------------------------



